/**
 * Copyright (c) 2020 wuchenxi
 * walter-blog is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * <p>
 * <p>
 * Mulan Permissive Software License，Version 2
 * <p>
 * Mulan Permissive Software License，Version 2 (Mulan PSL v2)
 * January 2020 http://license.coscl.org.cn/MulanPSL2
 */
package com.walter.blog.business.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.walter.aliyun.oss.getObject.GetOssFile;
import com.walter.aliyun.oss.putObject.OssUpload;
import com.walter.auth.SecurityUtil;
import com.walter.auth.config.user.BlogUser;
import com.walter.blog.business.content.service.ContentService;
import com.walter.db.mapper.*;
import com.walter.db.pojo.*;
import com.walter.response.ResponseKit;
import com.walter.util.PageUtil;
import com.walter.vo.content.ContentListVO;
import com.walter.vo.page.PageVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @author wuchenxi
 * @date 2020-08-08 10:43:36
 */
@Service
public class ContentServiceImpl extends ServiceImpl<ContentMapper, Content> implements ContentService {

    @Resource
    private ContentMapper contentMapper;

    @Resource
    private UserContentMapper userContentMapper;

    @Resource
    private HttpSession httpSession;

    @Resource
    private ViewCountMapper viewCountMapper;

    @Resource
    private UserCategoryMapper userCategoryMapper;

    @Resource
    private CategoryContentMapper categoryContentMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseKit<Object> addContent(Content content, String categoryId) {
        BlogUser user = SecurityUtil.getBlogUser();

        UserCategory userCategory = null;
        if (StringUtils.isNotEmpty(categoryId)) {
            userCategory = userCategoryMapper.selectByUserIdAndCategoryId(user.getId(), categoryId);
        }

        if (StringUtils.isNotEmpty(content.getId())) {
            // 说明当前文章之前是草稿
            content.setUpdateTime(new Date());
            content.setState(2);
            contentMapper.updateById(content);

            if (userCategory != null) {
                CategoryContent categoryContent = categoryContentMapper.selectByCategoryIdAndContentId(categoryId, content.getId());
                if (categoryContent == null) {
                    categoryContentMapper.insert(CategoryContent.builder()
                            .categoryId(categoryId)
                            .contentId(content.getId())
                            .createTime(new Date())
                            .updateTime(new Date())
                            .build());
                }
            }

            return ResponseKit.success();
        }

        if (StringUtils.isEmpty(content.getSecondTitle())) {
            content.setSecondTitle(content.getTitle());
        }
        content.setCreateTime(new Date());
        content.setUpdateTime(new Date());
        content.setState(2);
        contentMapper.insert(content);

        userContentMapper.insert(UserContent.builder()
                .contentId(content.getId())
                .userId(user.getId())
                .build());

        categoryContentMapper.insert(CategoryContent.builder()
                .categoryId(categoryId)
                .contentId(content.getId())
                .createTime(new Date())
                .updateTime(new Date())
                .build());

        return ResponseKit.success();
    }

    @Override
    public ResponseKit<PageVO<ContentListVO>> listContents(Integer pageNum, Integer pageSize, String content) {
        Page<ContentListVO> page = new Page<>(pageNum, pageSize);
        List<ContentListVO> list = contentMapper.selectOpenContent(page, content);
        page.setRecords(list);
        return ResponseKit.success(PageUtil.packagePage(page));
    }

    @Override
    public ResponseKit<PageVO<ContentListVO>> listMyContents(Integer pageNum, Integer pageSize, String content) {
        BlogUser user = SecurityUtil.getBlogUser();

        Page<ContentListVO> page = new Page<>(pageNum, pageSize);
        List<ContentListVO> list = contentMapper.selectByContents(page, user.getId(), content);
        page.setRecords(list);
        return ResponseKit.success(PageUtil.packagePage(page));
    }

    @Override
    public ResponseKit<Content> getContent(String id) {

        Content content = contentMapper.selectById(id);
        // 文章的作者id
        String userId = userContentMapper.selectUserIdByCountId(id);

        if (Objects.equals(content.getPushType(), 1)) {

            if (SecurityUtil.authenticated()) {
                this.saveViewCount(id);
                return ResponseKit.success(content);
            }


            BlogUser user = SecurityUtil.getBlogUser();
            if (!Objects.equals(user.getId(), userId)) {
                // 自己查看自己文章不增加阅读量
                this.saveViewCount(id);
            }
            return ResponseKit.success(content);
        }

        BlogUser user = SecurityUtil.getBlogUser();
        UserContent userContent = userContentMapper.selectOne(new LambdaQueryWrapper<UserContent>()
                .eq(UserContent::getUserId, user.getId())
                .eq(UserContent::getContentId, id));

        if (userContent == null) {
            return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "您没有权限查看！");
        }

        if (!Objects.equals(user.getId(), userId)) {
            // 自己查看自己文章不增加阅读量
            this.saveViewCount(id);
        }
        this.saveViewCount(id);

        return ResponseKit.success(content);
    }

    private void saveViewCount(String contentId) {
        viewCountMapper.insert(ViewCount.builder()
                .contentId(contentId)
                .createTime(new Date())
                .build());
    }

    @Override
    public ResponseKit<Object> canEdit(String id) {
        if (StringUtils.isEmpty(id)) {
            return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "不可编辑！");
        }

        BlogUser user = SecurityUtil.getBlogUser();
        UserContent userContent = userContentMapper.selectOne(new LambdaQueryWrapper<UserContent>()
                .eq(UserContent::getUserId, user.getId())
                .eq(UserContent::getContentId, id));
        if (userContent != null) {
            return ResponseKit.success();
        }
        return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "不可编辑！");
    }

    @Override
    public ResponseKit<Object> del(String id) {
        BlogUser user = SecurityUtil.getBlogUser();
        UserContent userContent = userContentMapper.selectOne(new LambdaQueryWrapper<UserContent>()
                .eq(UserContent::getUserId, user.getId())
                .eq(UserContent::getContentId, id));
        if (userContent == null) {
            return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "不可删除！");
        }
        Content content = contentMapper.selectById(id);
        content.setState(3);
        content.setUpdateTime(new Date());
        contentMapper.updateById(content);
        return ResponseKit.success();
    }

    @Override
    public ResponseKit<Object> uploadImg(MultipartFile file) {

        BlogUser user = SecurityUtil.getBlogUser();

        String upload = OssUpload.upload(file, "img/content/" + user.getId() + "/");

        Map<String, String> map = new HashMap<>(16);
        map.put("url", GetOssFile.getPublicObjectUrl(upload));

        return ResponseKit.success(map);
    }

    @Override
    public ResponseKit<String> category(String contentId) {

        BlogUser user = SecurityUtil.getBlogUser();
        UserContent userContent = userContentMapper.selectByUserIdAndContentId(user.getId(), contentId);

        if (userContent == null) {
            return ResponseKit.success("");
        }

        String id = categoryContentMapper.selectCategoryIdByContentId(contentId);

        return ResponseKit.success(id);
    }
}
